/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package gabanet;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;

/**
 *
 * @author Libra
 */
public class Culture {
    int dim_h,dim_v;
    int density;
    int area=dim_h*dim_v;
    int nNeuron=area*density;
    int nGlu,nGABA;
    int nGluConn, nGABAConn;
    final int GABA_WO_GABA_IN=1;
    final int GLU_W_GABA_IN=2;
    final int GLU_WO_GABA_IN=3;
    
    Neurons neuron[]=new Neurons[nNeuron];
    SynapticConnection connection[];
    //TODO Move calculations to methods;
    
    
    void seedNeuron() {
        ArrayList<Boolean> GABAList=new ArrayList<>(nNeuron);
        Random seedRand=new Random();

        /*
         * Set Some of the neuron Glu
         * Java boolean default values equal false
         * Then randomly assign x,y coordinate to neurons
         */

        /*
         * I'm convinced now that
         * no need to shuffle here
         */
        
        //TODO if really no shuffle is needed, no list is needed either.
        
        for (int i=0;i<nGABA;i++) {
            GABAList.add(true);
        }
        for (int i=0;i<nGlu;i++) {
            GABAList.add(false);
        }
//        Collections.shuffle(GABAList);
        
        for (int i=0;i<nNeuron;i++) {
            neuron[i].setGABA(GABAList.get(i));
            neuron[i].Geo.setXY(seedRand.nextInt(dim_h), 
                                seedRand.nextInt(dim_v));
        }
    }
    
    /*
     * Util method to return connection probility as a function of distance
     */
    
    float connProb(int connType, int dist) {
        float prob;
        float gluProb=1, GABAProb=1;
        //TODO !!!Gaba and Glu Connection Probility 
        switch (connType) {
            case GABA_WO_GABA_IN:
                return GABAProb;
            case GLU_W_GABA_IN:
                return gluProb;
            case GLU_WO_GABA_IN:
                return gluProb;
            default:
                return gluProb;
        }
    }
    
    void randomGrowth() {
        //TODO form connections
         
         
        
    }
    
    void Growth(){
        int idx;
        int tempPre;
        int tempPost;
        int nLeft;
        nLeft=nNeuron;
        int randTemp;
        int dist;
        Random growthRand=new Random();
        int gluConnRemain, GABAConnRemain;
        float prob;
        gluConnRemain=nGluConn;
        GABAConnRemain=nGABAConn;
        boolean connMatrix[][]=new boolean[nNeuron][nNeuron];
        
        /*
         * Connect GABA synapses
         */
        while (GABAConnRemain>0){
            tempPre=growthRand.nextInt(nGABA);
            //TODO maybe check is still needed
            tempPost=growthRand.nextInt(nNeuron);
            if (tempPost==tempPre) continue;
            else {
                dist=neuron[tempPre].Geo.distanceFrom(neuron[tempPost]);
                prob=connProb(GABA_WO_GABA_IN, dist);
                if ((growthRand.nextFloat() < prob)
                          && (connMatrix[tempPre][tempPost]!=true)) {
                    connMatrix[tempPre][tempPost]=true;
                    GABAConnRemain--;
                    neuron[tempPost].addGABAPre();
                    if (tempPost<nGABA) neuron[tempPre].addGABAPost();
                    else neuron[tempPre].addGluPost();
                }
            }
        }
        
        /*
         * Connect Glu Synapses
         */
        while (gluConnRemain>0) {
            tempPre=growthRand.nextInt(nGlu)+nGABA;
            tempPost=growthRand.nextInt(nNeuron);
            if (tempPost==tempPre) continue;
            else {
                dist=neuron[tempPre].Geo.distanceFrom(neuron[tempPost]);
                if (neuron[tempPre].GABAIn()>0)
                    prob=connProb(GLU_W_GABA_IN, dist);
                else prob=connProb(GLU_WO_GABA_IN,dist);
                if ((growthRand.nextFloat() < prob)
                          && (connMatrix[tempPre][tempPost]!=true)) {
                    connMatrix[tempPre][tempPost]=true;
                    gluConnRemain--;
                    neuron[tempPost].addGluPre();
                    if (tempPost<nGABA) neuron[tempPre].addGABAPost();
                    else neuron[tempPre].addGluPost();
                }                
            }
        }
    }
    
    
    Culture(){
        // TODO calc nGlu, nGABA
        // TODO import area, density;
        
    }
    
}
